package com.example.mybatis.binding;

import cn.hutool.core.lang.ClassScanner;
import com.example.mybatis.session.Configuration;
import com.example.mybatis.session.SqlSession;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* @Description: Mapper注册器
* @Param: 
* @return: 
* @Author: tangzhaofeng
* @Date: 5/17/2024
*/
public class MapperRegistry {

    private Configuration configuration;

    public MapperRegistry(Configuration configuration){
        this.configuration = configuration;
    }


    /**
     * @Description 定义一个缓存Mapper映射表
     * @Author T
     * @Date 2024/5/20 18:34
     **/
    private final Map<Class<?>,MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>,MapperProxyFactory<?>>();

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        final  MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        if (mapperProxyFactory == null){
            //注册器没有扫描到该类型接口
            throw new RuntimeException("Type " + type + " is not registered!");
        }
        return mapperProxyFactory.newInstance(sqlSession);
    }


    /**
     * @Description 添加Mapper
     * @Author T
     * @Date 2024/5/20 18:33     
     **/
    public <T> void addMapper(Class<T> type) {
        /* Mapper 必须是接口才会注册 */
        if (type.isInterface()) {
            if (hasMapper(type)) {
                // 如果重复添加了，报错
                throw new RuntimeException("Type " + type + " is already known to the MapperRegistry.");
            }
            // 注册映射器代理工厂
            knownMappers.put(type, new MapperProxyFactory<>(type));
        }
    }

    /* 判断是否注册过 */
    public <T> boolean hasMapper(Class<T> type) {
        return knownMappers.containsKey(type);
    }

    public void addMappers(String packageName) {
        Set<Class<?>> mapperSet = ClassScanner.scanPackage(packageName);
        for (Class<?> mapperClass : mapperSet) {
            addMapper(mapperClass);
        }
    }

}
